<template>
	<div>
		<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset" v-if="getPropsRef.schemas" style="margin-bottom: 10px">
			<template #statusSlot="{ model, field }">
				<n-input v-model:value="model[field]" />
			</template>
		</BasicForm>
		<div class="table-toolbar">
			<!--顶部左侧区域-->
			<div class="flex items-center table-toolbar-left">
				<slot name="tableTitle"></slot>
			</div>
			<div class="flex items-center table-toolbar-right">
				<!--顶部右侧区域-->
				<slot name="toolbar"></slot>
				<div class="table-toolbar-right-icon">
					<n-dropdown v-if="getPropsRef.exportInfo" @select="densitySelect" trigger="hover" :options="exportOptions">
						<div class="header-iconfont">
							<i class="iconfont icon-export"></i>
						</div>
					</n-dropdown>
				</div>
			</div>
		</div>
		<n-data-table
			ref="tableElRef"
			:bordered="false"
			v-bind="getAttrsBind"
			:row-key="
				(rowData) => {
					return rowData.id;
				}
			"
			v-model:checked-row-keys="checkedRowKeys"
			@update:checked-row-keys="updateCheckRow"
			@update:sorter="setSorterQuery">
			<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
				<slot :name="item" v-bind="data"></slot>
			</template>
		</n-data-table>
		<n-pagination class="table-pagination" v-if="getAttrsBind.data.length" v-bind="pagination" @update:page="updatePage" @update:page-size="updatePageSize" />
	</div>
</template>

<script lang="ts" setup>
	import { QueryCondition } from '@/components/Table/src/type';
	import { DataTableSortState } from 'naive-ui';
	import { useColumns } from '@/components/Table/src/hook/useColumns';
	import { useLoading } from '@/components/Table/src/hook/useLoading';
	import { useFilter } from '@/components/Table/src/hook/useFilter';
	import { usePagination } from '@/components/Table/src/hook/usePagination';
	import { useDataSource } from '@/components/Table/src/hook/useDataSource';
	import { filterRenderType } from '@/components/Table/src/enum/filterRenderType';
	import { useForm } from '@/components/Form';
	import { exportFile } from '@/utils/exportByUrl';
	import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn';
	import { propTypes } from '@/utils/propTypes';
	import { getViewportOffset } from '@/utils/domUtils';
	import { isBoolean } from '@/utils/is';
	const checkedRowKeysRef = ref([]);
	const checkedRowKeys = checkedRowKeysRef;
	// defineProps({
	// 	canResize: propTypes.bool.def(true)
	// })
  const slot = useSlots()
  const hasCheck = computed(() => {
		return !checkedRowKeys.value.length;
	});
	const exportOptions = reactive([
		{
			label: '导出全部',
			key: 1,
		},
		{
			label: '导出选择',
			key: 2,
			disabled: hasCheck,
		},
	]);

	const queryCondition: QueryCondition = {
		filterConditions: [],
		pageCondition: {
			pageNum: 1,
			pageSize: 10,
		},
		sortCondition: {},
		bizCondition: null,
	};
  // 默认高度
	const deviceHeight = ref(150);

	const tableElRef = ref(null);
	let paginationEl: HTMLElement | null;
	const attrs = useAttrs();
	const getPropsRef = computed(() => {
		return attrs;
	});
	const { getLoading, setLoading } = useLoading(getPropsRef);
	const { getColumnsRef, getColumnsHandle, withFilterCol, clearFilterOptionValue, clearSortOptionValue } = useColumns(getPropsRef, setLoading);
	const { getFilterChange } = useFilter(withFilterCol, setLoading);
	const { getPaginationInfo, setPagination, getPagination } = usePagination(getPropsRef);

	/*单列排序进行处理*/
	const setSorterQuery = (options: DataTableSortState | null) => {
		getColumnsHandle.value.forEach((column) => {
			if (column.sortOrder === undefined) return;
			if (!options) {
				column.sortOrder = false;
				return;
			}
			if (column.key === options.columnKey) column.sortOrder = options.order;
			else column.sortOrder = false;
		});
		queryCondition.sortCondition = options.order
			? {
					sortField: options.columnKey,
					sortRule: options.order === 'ascend' ? 'asc' : 'desc',
			  }
			: {};
		reload(queryCondition);
	};

	watch(
		() => unref(getFilterChange),
		(n, o) => {
			let p = {};
			let filter = [];
			n.map((item) => {
				p[item.key] = item.filterOptionValue;
				if (item.type === filterRenderType.DATERANGEPICKER) {
					filter.push({
						filterField: item.key,
						filterValue: item.filterOptionValue[0],
						operator: 'gte',
						extra: 'LT_AND_GT',
					});
					filter.push({
						filterField: item.key,
						filterValue: item.filterOptionValue[1],
						operator: 'lte',
						extra: 'LT_AND_GT',
					});
				} else {
					filter.push({  
						filterField: item.key,
						filterValue: item.filterOptionValue,
						operator: item.type === filterRenderType.INPUT ? 'contains' : 'eq',
					});
				}
			});
			queryCondition.pageCondition.pageNum=1
			queryCondition.filterConditions = filter;
			tableElRef.value.filter(p);
			reload(queryCondition);
		}
	);

	const resetFilter = () => {
		clearFilterOptionValue();
		clearCheckRow();
		queryCondition.filterConditions = [];
		tableElRef.value.filter({});
		reload(queryCondition);
	};
	const resetQueryCondition = () => {
		clearFilterOptionValue();
		clearSortOptionValue();
		clearCheckRow();
		queryCondition.filterConditions = [];
		queryCondition.sortCondition = {};
		queryCondition.bizCondition = null;
		tableElRef.value.filter({});
		setPagination({ page: 1, pageSize: queryCondition.pageCondition.pageSize });
	};

	//页码切换
	function updatePage(page) {
		setPagination({ page: page });
		queryCondition.pageCondition.pageNum = page;
		reload(queryCondition);
	}

	//分页数量切换
	function updatePageSize(size) {
		queryCondition.pageCondition.pageSize = size;
		queryCondition.pageCondition.pageNum = 1;
		setPagination({ page: 1, pageSize: size });
		reload(queryCondition);
	}

	const tableData = ref<Recordable[]>([]);
	const emit = defineEmits(['fetch-success', 'fetch-error', 'update:checked-row-keys']);
	const exportInfo: any = unref(getPropsRef).exportInfo;

	const densitySelect = ($event) => {
		if ($event === 1) {
			const req = {
				exportType: exportInfo.exportType,
				columnName: exportInfo.columnName,
				queryCondition: queryCondition,
			};
			exportFile(exportInfo.exportAllUrl, req, `${exportInfo.exportName}${new Date().getTime()}.xlsx`);
		} else {
			const req = {
				exportType: exportInfo.exportType,
				columnName: exportInfo.columnName,
			};
			req['ids'] = checkedRowKeys.value;
			exportFile(exportInfo.exportSelectUrl, req, `${exportInfo.exportName}${new Date().getTime()}.xlsx`);
		}
	};
	const { getDataSourceRef, getDataSource, getRowKey, reload } = useDataSource(
		getPropsRef,
		{
			getPaginationInfo,
			setPagination,
			tableData,
			setLoading,
		},
		emit
	);
	const pagination = computed(() => toRaw(unref(getPaginationInfo)));
	/*组装prop*/
	const getAttrsBind = computed(() => {
		const tableData = unref(getDataSourceRef);
		const maxHeight = tableData.length ? `${unref(deviceHeight)}px` : 'auto';
		return {
			columns: unref(getColumnsHandle),
			data: tableData,
			loading: unref(getLoading),
			'max-height': maxHeight,
		};
	});

	const [register, {}] = useForm({
		gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
		labelWidth: 80,
		schemas: unref(getPropsRef).schemas || [],
	});

	function handleSubmit(values: Recordable) {
		Object.keys(values).map((item) => {
			if (values[item] === '' || values[item] == null) {
				delete values[item];
			}
		});
		resetQueryCondition();
		queryCondition.bizCondition = values;
		reload(queryCondition);
	}

	function handleReset(values: Recordable) {
		resetQueryCondition();
		reload(queryCondition);
	}

	function updateCheckRow(e) {
		checkedRowKeysRef.value = e;
		emit('update:checked-row-keys', checkedRowKeys);
	}

	function clearCheckRow() {
		checkedRowKeysRef.value = [];
	}
	function getCheckRowKeys() {
		return toRaw(unref(checkedRowKeysRef));
	}
	const getCanResize = computed(() => {
		const { canResize } = unref(getPropsRef);
		return canResize;
	});

	async function computeTableHeight() {
		const table = unref(tableElRef);
		if (!table) return;
		if (!unref(getCanResize)) return;
		const tableEl: any = table?.$el;
		const headEl = tableEl.querySelector('.n-data-table-thead ');
		const { bottomIncludeBody } = getViewportOffset(headEl);
		const headerH = 64;
		let paginationH = 2;
		let marginH = 24;
		if (!isBoolean(pagination)) {
			paginationEl = tableEl.querySelector('.n-pagination') as HTMLElement;
			if (paginationEl) {
				const offsetHeight = paginationEl.offsetHeight;
				paginationH += offsetHeight || 0;
			} else {
				paginationH += 28;
			}
		}
		let height = bottomIncludeBody - (headerH + paginationH + marginH + (unref(getPropsRef).resizeHeightOffset || 0));
		const maxHeight = unref(getPropsRef).maxHeight;
		height = maxHeight && maxHeight < height ? maxHeight : height;
		deviceHeight.value = height;
	}

	useWindowSizeFn(computeTableHeight, 280);

	onMounted(() => {
		nextTick(() => {
			computeTableHeight();
		});
	});
	defineExpose({
		reload,
		clearCheckRow,
		getCheckRowKeys,
	});
</script>

<style scoped lang="less">
	.table-toolbar {
		display: flex;
		justify-content: space-between;
		padding: 0 0 16px 0;

		&-left {
			display: flex;
			align-items: center;
			justify-content: flex-start;
			flex: 1;

			&-title {
				display: flex;
				align-items: center;
				justify-content: flex-start;
				font-size: 16px;
				font-weight: 600;
			}
		}

		&-right {
			display: flex;
			justify-content: flex-end;
			flex: 1;

			&-icon {
				margin-left: 12px;
				font-size: 16px;
				cursor: pointer;
				color: var(--text-color);

				:hover {
					color: #1890ff;
				}
			}
		}
	}

	.table-toolbar-inner-popover-title {
		padding: 2px 0;
	}
	.table-pagination {
		float: right;
		margin-top: 20px;
	}
	.header-iconfont {
		background-color: #e7e8ed;
		border-radius: 2px;
		cursor: pointer;

		i {
			margin-left: 5px;
			color: #323954;
		}
	}
</style>
